
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvTimer.h"
#include "contiki.h"

#define SR04_TRIGGER_HIGH()		DrvGPIO_SetBit(E_GPB, 13)
#define SR04_TRIGGER_LOW()		DrvGPIO_ClrBit(E_GPB, 13)

#define SR04_NONE		0
#define SR04_TRIGGER	1
#define SR04_WAIT		2
#define SR04_FINISH		3

static uint8_t u8Sr04State;
static unsigned long long  u64Time;

static void sr04_eint0callback(void)
{
	switch(u8Sr04State)
	{
		case SR04_TRIGGER:
			u64Time = clock_usec();
			u8Sr04State = SR04_WAIT;			
			break;
		case SR04_WAIT:
			u64Time = clock_usec()-u64Time;
			u8Sr04State = SR04_FINISH;			
			break;
		default:
			break;
	}
}

void Sr04_init(void)
{
	DrvGPIO_SetDebounceTime(10, E_DBCLKSRC_10K);    
	DrvGPIO_EnableDebounce(E_GPB, 14);
	DrvGPIO_InitFunction(E_FUNC_EXTINT0);

	DrvGPIO_Open(E_GPB, 13, E_IO_OUTPUT);
	SR04_TRIGGER_LOW();
	u8Sr04State = SR04_NONE;
}

void Sr04_StartTrigger(void)
{
	u8Sr04State = SR04_TRIGGER;
	DrvGPIO_EnableEINT0(E_IO_BOTH_EDGE, E_MODE_EDGE, sr04_eint0callback);
	SR04_TRIGGER_HIGH();
	clock_delay_usec(50);
	SR04_TRIGGER_LOW();
}

void Sr04_StopTrigger(void)
{
	DrvGPIO_DisableEINT0();
	u8Sr04State = SR04_NONE;
}

int32_t Sr04_GetDistance(uint16_t u16Timeout)
{
	uint32_t u32Time;
	if(u8Sr04State != SR04_NONE)
	{
		u32Time = clock_time();
		while(u8Sr04State != SR04_FINISH)
		{
			if(clock_diff(u32Time) >  u16Timeout)
			{
				Sr04_StopTrigger();
				return -1;
			}
		}

		return u64Time/58;		// unit cm, 340/s u64Time/2/1000000*340*100 = u64Time/58
	}

	return -1;
}


